import { Request } from '../models/request.model';
import { StorageService } from '../services/storage.service';
import { HttpService } from '../services/http.service';
import { MessageService, MessageType, Message } from '../services/message.service';

/**
 * 扩展请求详情接口，包含请求头信息
 */
interface ExtendedWebRequestDetails extends chrome.webRequest.WebRequestDetails {
  requestHeaders?: chrome.webRequest.HttpHeader[];
}

/**
 * 存储键枚举，用于持久化数据
 */
enum BackgroundStorageKey {
  CAPTURED_REQUESTS = 'captured_requests',
  TAB_REQUESTS = 'tab_requests'
}

/**
 * 背景脚本类
 * 负责处理所有后台任务和网络请求
 */
class BackgroundScript {
  /**
   * 捕获的请求数据
   */
  private capturedRequests: Map<string, ExtendedWebRequestDetails> = new Map();
  
  /**
   * 按标签页分组的请求记录
   */
  private tabRequests: Map<number, ExtendedWebRequestDetails[]> = new Map();

  /**
   * 构造函数
   */
  constructor() {
    this.initialize();
  }

  /**
   * 初始化背景脚本
   */
  private async initialize(): Promise<void> {
    console.log('WebPost 背景脚本初始化');
    
    // 从存储中恢复数据
    await this.loadDataFromStorage();
    
    this.setupListeners();
    
    // 每5分钟保存一次数据到存储（防止Service Worker被终止）
    setInterval(() => this.saveDataToStorage(), 5 * 60 * 1000);
  }

  /**
   * 从存储中加载数据
   */
  private async loadDataFromStorage(): Promise<void> {
    try {
      // 加载捕获的请求
      const capturedData = await chrome.storage.local.get(BackgroundStorageKey.CAPTURED_REQUESTS);
      if (capturedData[BackgroundStorageKey.CAPTURED_REQUESTS]) {
        const savedRequests = JSON.parse(capturedData[BackgroundStorageKey.CAPTURED_REQUESTS]);
        this.capturedRequests = new Map(Object.entries(savedRequests));
      }
      
      // 加载标签页请求
      const tabRequestsData = await chrome.storage.local.get(BackgroundStorageKey.TAB_REQUESTS);
      if (tabRequestsData[BackgroundStorageKey.TAB_REQUESTS]) {
        const savedTabRequests = JSON.parse(tabRequestsData[BackgroundStorageKey.TAB_REQUESTS]);
        // 转换为Map结构
        this.tabRequests = new Map();
        for (const [tabId, requests] of Object.entries(savedTabRequests)) {
          this.tabRequests.set(Number(tabId), requests as ExtendedWebRequestDetails[]);
        }
      }
      
      console.log('成功从存储中恢复数据', 
        this.capturedRequests.size, '个捕获请求,', 
        this.tabRequests.size, '个标签页数据');
    } catch (error) {
      console.error('从存储中加载数据时出错:', error);
      // 出错时使用空数据
      this.capturedRequests = new Map();
      this.tabRequests = new Map();
    }
  }
  
  /**
   * 将数据保存到存储
   */
  private async saveDataToStorage(): Promise<void> {
    try {
      // 将Map转换为对象以便存储
      const capturedRequestsObj: Record<string, ExtendedWebRequestDetails> = {};
      for (const [key, value] of this.capturedRequests.entries()) {
        capturedRequestsObj[key] = value;
      }
      
      // 将标签页请求Map转换为对象
      const tabRequestsObj: Record<string, ExtendedWebRequestDetails[]> = {};
      for (const [tabId, requests] of this.tabRequests.entries()) {
        tabRequestsObj[String(tabId)] = requests;
      }
      
      // 存储捕获的请求
      await chrome.storage.local.set({
        [BackgroundStorageKey.CAPTURED_REQUESTS]: JSON.stringify(capturedRequestsObj)
      });
      
      // 存储标签页请求
      await chrome.storage.local.set({
        [BackgroundStorageKey.TAB_REQUESTS]: JSON.stringify(tabRequestsObj)
      });
      
      console.log('成功保存数据到存储');
    } catch (error) {
      console.error('保存数据到存储时出错:', error);
    }
  }

  /**
   * 设置事件监听器
   */
  private setupListeners(): void {
    // 监听网络请求
    chrome.webRequest.onBeforeRequest.addListener(
      this.handleWebRequest.bind(this),
      { urls: ['<all_urls>'] },
      ['requestBody']
    );

    // 监听网络请求头
    chrome.webRequest.onSendHeaders.addListener(
      this.handleSendHeaders.bind(this),
      { urls: ['<all_urls>'] },
      ['requestHeaders']
    );

    // 监听消息
    MessageService.addListener(this.handleMessage.bind(this));

    // 监听标签关闭
    chrome.tabs.onRemoved.addListener(this.handleTabClosed.bind(this));
    
    // 监听Service Worker唤醒事件
    chrome.runtime.onStartup.addListener(() => {
      console.log('Service Worker启动');
      this.loadDataFromStorage();
    });
  }

  /**
   * 处理网络请求
   * @param details 请求详情
   */
  private handleWebRequest(details: chrome.webRequest.WebRequestDetails): void {
    // 忽略WebPost自己的请求和扩展相关请求
    if (this.isExtensionRequest(details.url)) {
      return;
    }

    // 保存请求详情
    this.capturedRequests.set(`${details.tabId}:${details.requestId}`, details as ExtendedWebRequestDetails);
    
    // 按标签页分组保存请求
    if (!this.tabRequests.has(details.tabId)) {
      this.tabRequests.set(details.tabId, []);
    }
    
    const tabRequestList = this.tabRequests.get(details.tabId);
    if (tabRequestList) {
      // 限制每个标签页最多保存100条请求记录
      if (tabRequestList.length >= 100) {
        tabRequestList.shift(); // 移除最旧的请求
      }
      tabRequestList.push(details as ExtendedWebRequestDetails);
      
      // 定时保存数据到存储（节流处理，避免频繁写入）
      this.debouncedSaveData();
    }
  }
  
  /**
   * 用于节流保存数据的函数
   */
  private debouncedSaveData = (() => {
    let timeoutId: number | null = null;
    return () => {
      if (timeoutId) {
        clearTimeout(timeoutId);
      }
      timeoutId = setTimeout(() => {
        this.saveDataToStorage();
        timeoutId = null;
      }, 5000) as unknown as number; // 5秒后保存
    };
  })();

  /**
   * 处理发送的请求头
   * @param details 请求头详情
   */
  private handleSendHeaders(details: chrome.webRequest.WebRequestHeadersDetails): void {
    // 忽略WebPost自己的请求和扩展相关请求
    if (this.isExtensionRequest(details.url)) {
      return;
    }

    // 获取已保存的请求
    const key = `${details.tabId}:${details.requestId}`;
    const capturedRequest = this.capturedRequests.get(key);
    
    if (capturedRequest) {
      // 添加请求头信息
      capturedRequest.requestHeaders = details.requestHeaders;
      this.capturedRequests.set(key, capturedRequest);
      
      // 更新标签页中的请求
      const tabRequestList = this.tabRequests.get(details.tabId);
      if (tabRequestList) {
        const requestIndex = tabRequestList.findIndex(req => req.requestId === details.requestId);
        if (requestIndex >= 0) {
          tabRequestList[requestIndex].requestHeaders = details.requestHeaders;
        }
      }
      
      // 定时保存数据到存储
      this.debouncedSaveData();
    }
  }

  /**
   * 处理标签关闭
   * @param tabId 关闭的标签ID
   */
  private async handleTabClosed(tabId: number): Promise<void> {
    // 清理该标签的请求数据
    for (const key of this.capturedRequests.keys()) {
      if (key.startsWith(`${tabId}:`)) {
        this.capturedRequests.delete(key);
      }
    }
    
    // 清理该标签的请求记录
    this.tabRequests.delete(tabId);
    
    // 保存更新后的数据
    await this.saveDataToStorage();
  }

  /**
   * 处理消息
   * @param message 消息
   * @param sender 发送者
   * @param sendResponse 响应函数
   */
  private async handleMessage(
    message: Message,
    sender: chrome.runtime.MessageSender,
    sendResponse: (response?: any) => void
  ): Promise<void> {
    console.log('Background received message:', message.type);
    
    switch (message.type) {
      case MessageType.GET_ACTIVE_TAB_REQUEST:
        await this.handleGetActiveTabRequest(sendResponse);
        break;
      
      case MessageType.GET_TAB_REQUESTS:
        await this.handleGetTabRequests(message.data?.tabId, sendResponse);
        break;
        
      case MessageType.SEND_REQUEST:
        await this.handleSendRequest(message.data?.request, sendResponse);
        break;
      
      case MessageType.SAVE_REQUEST:
        await this.handleSaveRequest(message.data?.request, sendResponse);
        break;
      
      default:
        console.warn('Unknown message type:', message.type);
        sendResponse({ success: false, error: 'Unknown message type' });
    }
  }

  /**
   * 处理获取当前标签页请求
   * @param sendResponse 响应函数
   */
  private async handleGetActiveTabRequest(sendResponse: (response?: any) => void): Promise<void> {
    try {
      // 获取当前活动标签
      const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
      if (tabs.length === 0 || !tabs[0].id) {
        sendResponse({ success: false, error: '无法获取活动标签页' });
        return;
      }
      
      const tabId = tabs[0].id;
      
      // 查找最新的请求
      let latestRequest: ExtendedWebRequestDetails | null = null;
      let latestTimestamp = 0;
      
      for (const [key, request] of this.capturedRequests.entries()) {
        if (key.startsWith(`${tabId}:`) && request.timeStamp > latestTimestamp) {
          latestRequest = request;
          latestTimestamp = request.timeStamp;
        }
      }
      
      if (!latestRequest) {
        sendResponse({ success: false, error: '未找到请求' });
        return;
      }
      
      // 创建Request对象
      const request = Request.fromNetworkRequest(latestRequest);
      
      sendResponse({ success: true, request });
    } catch (error) {
      console.error('Error handling get active tab request:', error);
      sendResponse({ success: false, error: String(error) });
    }
  }
  
  /**
   * 处理获取标签页所有请求
   * @param tabId 标签页ID
   * @param sendResponse 响应函数
   */
  private async handleGetTabRequests(tabId: number | undefined, sendResponse: (response?: any) => void): Promise<void> {
    try {
      if (!tabId) {
        // 如果没有指定标签页ID，则获取当前活动标签页
        const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
        if (tabs.length === 0 || !tabs[0].id) {
          sendResponse({ success: false, error: '无法获取活动标签页' });
          return;
        }
        tabId = tabs[0].id;
      }
      
      // 获取该标签页的所有请求
      const requests = this.tabRequests.get(tabId) || [];
      
      // 将请求转换为Request对象
      const requestObjects = requests.map(req => Request.fromNetworkRequest(req));
      
      sendResponse({ 
        success: true, 
        requests: requestObjects,
        tabUrl: await this.getTabUrl(tabId)
      });
    } catch (error) {
      console.error('Error handling get tab requests:', error);
      sendResponse({ success: false, error: String(error) });
    }
  }

  /**
   * 处理发送请求
   * @param requestData 请求数据
   * @param sendResponse 响应函数
   */
  private async handleSendRequest(requestData: any, sendResponse: (response?: any) => void): Promise<void> {
    try {
      if (!requestData) {
        sendResponse({ success: false, error: '请求数据为空' });
        return;
      }
      
      // 创建请求对象
      const request = new Request(requestData);
      
      // 发送请求
      const response = await HttpService.sendRequest(request);
      
      // 保存到历史记录
      await StorageService.saveToHistory(request);
      
      // 确保响应对象被正确序列化
      sendResponse({ 
        success: true, 
        response: response.toJSON() 
      });
    } catch (error) {
      console.error('Error handling send request:', error);
      sendResponse({ success: false, error: String(error) });
    }
  }

  /**
   * 处理保存请求
   * @param requestData 请求数据
   * @param sendResponse 响应函数
   */
  private async handleSaveRequest(requestData: any, sendResponse: (response?: any) => void): Promise<void> {
    try {
      if (!requestData) {
        sendResponse({ success: false, error: '请求数据为空' });
        return;
      }
      
      // 创建请求对象
      const request = new Request(requestData);
      
      // 保存请求
      await StorageService.saveRequest(request);
      
      sendResponse({ success: true });
    } catch (error) {
      console.error('Error handling save request:', error);
      sendResponse({ success: false, error: String(error) });
    }
  }

  /**
   * 获取标签页URL
   * @param tabId 标签页ID
   * @returns 标签页URL
   */
  private async getTabUrl(tabId: number): Promise<string | null> {
    try {
      const tab = await chrome.tabs.get(tabId);
      return tab.url || null;
    } catch (error) {
      console.error('Error getting tab URL:', error);
      return null;
    }
  }

  /**
   * 检查URL是否是扩展请求
   * @param url URL
   * @returns 是否是扩展请求
   */
  private isExtensionRequest(url: string): boolean {
    return url.startsWith('chrome-extension://') || url.includes('chrome.google.com');
  }
}

// 创建背景脚本实例
new BackgroundScript(); 